home *** CD-ROM | disk | FTP | other *** search
- /* Sort ACMD */
-
- #include "MacHeaders"
- #include "stdlib.h"
- #include "SetUpA4.h"
-
- #define TRUE 1
- #define FALSE 0
- #define CR '\r'
-
- #undef DEBUG
-
-
- /* pointer to a function that returns an 'int' */
- typedef int (*FPtr)();
-
- /* global variables */
- long sortCol = 0;
- static char *qBase;
- static size_t qSize;
- static int (*qCompare)();
- static int (*q1Compare)();
- static void (*q1Swap)();
-
- static int std_compare(size_t, size_t);
- static void std_swap(size_t, size_t);
-
- static void qsort1(size_t, size_t);
- static void aqsort(void *, size_t, size_t, int (*)());
-
- FPtr theAlert;
-
- char *
- #ifdef DEBUG
- sort(text, alert, getVar, setVar, defineVar,deleteVar)
- #else
- main(text, alert, getVar, setVar, defineVar,deleteVar)
- #endif DEBUG
- char *text;
- FPtr getVar, setVar, defineVar, deleteVar, alert;
- {
- long lines,i;
- register char *ptr, *ptr2;
- char **ptrs, *toPtr;
- int endingCr = FALSE;
- int lineCompare();
-
- #ifndef DEBUG
- /* this self-modifying stuff will crash under A/UX... */
- RememberA0();
- SetUpA4();
-
- if (!getVar("sortColumn", &sortCol))
- {
- alert("Unable to access vars");
- DisposPtr(text);
- return NULL;
- }
- #endif DEBUG
- theAlert = alert;
-
- for (ptr = text, lines = 1; *ptr; ptr++) if (*ptr == CR) lines++;
- if (*(ptr - 1) == CR)
- {
- endingCr = TRUE;
- lines--;
- }
-
- if (!(ptrs = NewPtr(sizeof(char *) * (lines + 1)))) /* extra for an ending cr we don't use */
- {
- alert("sort: unable to allocate, error %d", MemError());
- #ifndef DEBUG
- RestoreA4();
- #endif DEBUG
- return text;
- }
-
- ptrs[0] = text;
- for (ptr = text, i = 1; *ptr; ptr++)
- {
- if (*ptr == CR) ptrs[i++] = ptr + 1;
- }
- *ptr = CR;
-
- aqsort(ptrs, (long)lines, (long)sizeof(char *), lineCompare);
-
- if (!(toPtr = NewPtr(GetPtrSize(text) + 1)))
- {
- alert("sort: unable to allocate, error %d", MemError());
- #ifndef DEBUG
- RestoreA4();
- #endif DEBUG
- return text;
- }
-
- for (i = 0, ptr2 = toPtr; i < lines; i++)
- {
- for (ptr = ptrs[i]; *ptr != CR;)
- {
- *ptr2++ = *ptr++;
- }
- *ptr2++ = CR;
- }
- if (endingCr)
- *ptr2++ = 0;
- else
- *(ptr2 - 1) = 0;
-
- /* paranoia */
- if ((ptr2 - toPtr) > GetPtrSize(toPtr))
- {
- alert("sort: overran bounds!");
- }
-
- /* clean up */
- DisposPtr(text);
-
- #ifndef DEBUG
- RestoreA4();
- #endif DEBUG
-
- return toPtr;
- }
-
-
- /* return first minus second */
- lineCompare(sptr1, sptr2)
- char **sptr1, **sptr2;
- {
- register char *ptr1 = *sptr1, *ptr2 = *sptr2;
- int i;
-
-
- for (i = 0; i < sortCol; i++)
- {
- if (*ptr1++ == CR)
- {
- return (*ptr2 == CR) ? 0 : -1;
- }
- if (*ptr2++ == CR)
- {
- return (1);
- }
- }
-
- for (; *ptr1 != CR; ptr1++, ptr2++)
- {
- if (*ptr1 != *ptr2)
- {
- if (*ptr2 == CR)
- {
- return (1);
- }
- else
- {
- return (*ptr1 - *ptr2);
- }
- }
- }
- return ((*ptr2 == CR) ? 0 : -1);
- }
-
-
-
-
- #ifdef DEBUG
- main()
- {
- char *text = "one\rtwo\rthree\r";
- char *ptr;
-
- ptr = NewPtr(200);
- memmove(ptr, text, (long)(strlen(text) + 1));
- ptr = sort(ptr);
- printf("Result: '%s'\n",ptr);
- }
- #endif DEBUG
-
- /*
- * qsort.c
- *
- * Copyright (c) 1989 Symantec Corporation. All rights reserved.
- *
- */
-
-
-
- /* ---------- standard quicksort ---------- */
-
-
- void
- aqsort(base, n, size, compare)
- void *base;
- size_t n, size;
- int (*compare)();
- {
- qBase = base;
- qSize = (size + 1) & ~1;
- qCompare = compare;
- _aqsort(n, std_compare, std_swap);
- }
-
-
- static int
- std_compare(i, j)
- size_t i, j;
- {
- return((*qCompare)(qBase + i * qSize, qBase + j * qSize));
- }
-
-
- static void
- std_swap(i, j)
- size_t i, j;
- {
- register void *p = qBase + i * qSize;
- register void *q = qBase + j * qSize;
-
- asm {
- move.l qSize,d0
- @1 move.b (p)+,d1
- eor.b d1,(q)+
- subq.l #1,d0
- bne.s @1
- }
- asm {
- move.l qSize,d0
- @2 move.b -(q),d1
- eor.b d1,-(p)
- subq.l #1,d0
- bne.s @2
- }
- asm {
- move.l qSize,d0
- @3 move.b (p)+,d1
- eor.b d1,(q)+
- subq.l #1,d0
- bne.s @3
- }
- }
-
-
- /* ---------- general quicksort ---------- */
-
-
- int
- _aqsort(n, compare, swap)
- size_t n;
- int (*compare)();
- void (*swap)();
- {
- q1Compare = compare;
- q1Swap = swap;
- qsort1(0, n);
- }
-
-
- /*
- * sort elements "first" through "last"-1
- *
- */
-
- static void
- qsort1(first, last)
- size_t first, last;
- {
- static size_t i; /* "static" to save stack space */
- size_t j;
-
- while (last - first > 1) {
- i = first;
- j = last;
- for (;;) {
- while (++i < last && (*q1Compare)(i, first) < 0)
- ;
- while (--j > first && (*q1Compare)(j, first) > 0)
- ;
- if (i >= j)
- break;
- (*q1Swap)(i, j);
- }
- if (j == first) {
- ++first;
- continue;
- }
- (*q1Swap)(first, j);
- if (j - first < last - (j + 1)) {
- qsort1(first, j);
- first = j + 1; /* qsort1(j + 1, last); */
- }
- else {
- qsort1(j + 1, last);
- last = j; /* qsort1(first, j); */
- }
- }
- }
-